import React from 'react';
import Tree from "antd/es/tree/Tree";
import {App, Button, Card, Divider, Flex, Space, Tag, TreeDataNode} from "antd";
import {Link} from "react-router-dom";
import useAsyncEffect from "hook/useAsyncEffect";
import RequestHandler from "http/RequestHandler";
import {treeIconTransition} from "util/icon-util";
import {CloudUploadOutlined, ReloadOutlined, RollbackOutlined} from "@ant-design/icons";
import {compareArray} from "util/compare";
export type TreeDataNodeProps = TreeDataNode & { /** 对于标题的描述 */ explain: string };
interface TreeEnhanceProps {
    /**
     * 操作数的主要id,如果操作用户权限,则是用户id
     */
    optionId: number;
    /**
     * 树渲染数据请求地址,结尾必须有/
     */
    dataUrl: string;
    /**
     * 树数据更新请求地址
     */
    updateUrl: string;
    /**
     * 刷新权限请求地址
     */
    refreshUrl?: string;
    /**
     * 刷新菜单树请求地址
     */
    refreshTreeUrl?: string;
    /**
     * 标题
     */
    title: string;
    /**
     * 副标题
     */
    subText?: string;
    /**
     * 标签信息
     */
    tagInfo?: string;
    /**
     * 反回按钮显示文本
     */
    backupText?: string;
    /**
     * 页脚
     */
    footer?: React.ReactNode,
    /**
     * 树节点渲染函数
     * @param nodeData 树节点数据
     */
    titleRender?: (nodeData: TreeDataNodeProps) => React.ReactNode | undefined
}
export type AuthorityTreeData = {
    /**
     * 渲染树需要的数据源
     */
    treeData: TreeDataNodeProps[],
    /**
     * 默认选中的树节点key数组
     */
    authorityKeys: React.Key[],
    /**
     * 默认展开的树节点key数组
     */
    expandKeys: React.Key[],
}
const TreeEnhance = (props: TreeEnhanceProps) => {
    const initChecked = React.useRef<React.Key[]>([]);
    const [treeData, setTreeData] = React.useState<TreeDataNode[]>();
    const [checkedKeys, setCheckedKeys ] = React.useState<React.Key[]>();
    const [expandedKeys, setExpandedKeys] = React.useState<React.Key[]>();
    const [isModify, setIsModify] = React.useState<boolean>(false);
    const [isCommit, setIsCommit] = React.useState<boolean>(false);
    const { message } = App.useApp();
    useAsyncEffect( async () => {
        const preData = await RequestHandler.get<AuthorityTreeData>(props.dataUrl + props.optionId);
        if (!preData.success){
            return;
        }
        treeIconTransition(preData.data.treeData);
        setTreeData(preData.data.treeData);
        setCheckedKeys(preData.data.authorityKeys);
        setExpandedKeys(preData.data.expandKeys);
        initChecked.current = preData.data.authorityKeys;
    });
    const onCheck = (checked: React.Key[] | {checked: React.Key[] ; halfChecked: React.Key[]}) => {
        if (compareArray(initChecked.current, checked as React.Key[]) !== null){
            setIsModify(true);
        }else {
            setIsModify(false);
        }
        setCheckedKeys(checked as React.Key[]);
    };
    const onExpand = (expandedKeys: React.Key[]) => {
        setExpandedKeys(expandedKeys);
    };
    /**
     * 撤销修改
     */
    const unmodify = () => {
        setCheckedKeys(initChecked.current);
        setIsModify(false);
    };
    /**
     * 提交修改
     */
    const commit = async () => {
        const compRes = compareArray(initChecked.current, checkedKeys as React.Key[], props.optionId);
        if (compRes === null){
            message.info("数据没有任何修改");
            return;
        }
        const res = await RequestHandler.post<number>(props.updateUrl, compRes);
        if (res.success && res.data > 0){
            setIsCommit(true);
            setIsModify(false);
            initChecked.current = checkedKeys as React.Key[];
            message.success("数据修改成功");
        }else {
            message.warning("数据修改失败");
        }
    };
    const refreshAuthority = async () => {
        if (props.refreshUrl){
            const res = await RequestHandler.get<number>(props.refreshUrl);
            if (res.success && res.data > 0){
                message.success("权限刷新成功");
            }else {
                message.warning("权限刷新失败");
            }
        }
        setIsCommit(false);
    };
    const refreshTree = async () => {
        if (props.refreshTreeUrl){
            await RequestHandler.get<number>(props.refreshTreeUrl);
            message.success("刷新树数据成功!");
        }
    };

    const tr = (node: TreeDataNode) => {
        if (props.titleRender){
            return props.titleRender(node as TreeDataNodeProps);
        }
        return node.title as String;
    };

    return (
        <Card title={
            <Space>
                {props.title} [
                <span style={{ fontSize: "14px", fontWeight: "bold" }}>{props.subText}</span>
                <Tag color={"green"}>{props.tagInfo}</Tag>]
            </Space>
        } extra={<Link to={".."}>{props.backupText}</Link>}>
            <Flex justify={"space-between"}>
                <Space>
                    <Button disabled={!isModify} type={"primary"} icon={<CloudUploadOutlined/>} onClick={commit}
                    >提交修改</Button>
                    <Button disabled={!isCommit} type={"primary"} icon={<ReloadOutlined/>} onClick={refreshAuthority}
                    >刷新权限</Button>
                    <Button disabled={!props.refreshTreeUrl} type={"primary"} icon={<ReloadOutlined/>} onClick={refreshTree}
                    >刷新树</Button>
                </Space>
                <Button disabled={!isModify} type={"primary"} icon={<RollbackOutlined/>} onClick={unmodify}
                >撤销修改</Button>
            </Flex>
            <Divider/>
            <Tree
                titleRender={tr}
                style={{marginLeft: "20px"}}
                showIcon
                checkable
                treeData={treeData}
                expandedKeys={expandedKeys}
                checkedKeys={checkedKeys}
                onCheck={onCheck}
                onExpand={onExpand}
            >
            </Tree>
            {props.footer ? <Divider/> : null}
            {props.footer}
        </Card>
    );
};

export default TreeEnhance;